package pers.kw.server.service;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pers.kw.dto.UpdateAcctBalanceReqDto;
import pers.kw.enums.DebitCreditEnum;
import pers.kw.exceptions.BizException;
import pers.kw.server.persist.dao.AccountInfoDao;
import pers.kw.server.persist.dao.AccountTranDetailDao;
import pers.kw.server.persist.entity.AccountInfoDO;
import pers.kw.server.persist.entity.AccountTranDetailDO;
import pers.kw.utils.DoWrapUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * 用户资金账户
 */
@Service
@Slf4j
public class AccountService {

    @Resource
    private AccountInfoDao accountInfoDao;

    @Resource
    private AccountTranDetailDao accountTranDetailDao;


    public BigDecimal queryAcctBalance(String userNo) {
        log.info("[userNo:{}]查询账户余额start...", userNo);
        AccountInfoDO accountInfoDO = accountInfoDao.findByUserNo(userNo);
        if (accountInfoDO == null) {
            throw new BizException("用户资金账户信息不存在");
        }
        log.info("[userNo:{}]查询账户余额end... 出参:{}", userNo, JSON.toJSONString(accountInfoDO));
        return accountInfoDO.getBalance();
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateAcctBalance(UpdateAcctBalanceReqDto reqDto) {
        log.info("更新账户余额start... 入参:{}", JSON.toJSONString(reqDto));
        AccountInfoDO accountInfoDO = accountInfoDao.findByUserNo(reqDto.getUserNo());
        if (accountInfoDO == null) {
            throw new BizException("用户资金账户信息不存在");
        }
        //更新账户信息
        if (reqDto.getAmt().compareTo(accountInfoDO.getBalance()) > 0) {
            throw new BizException("账户余额不足");
        }
        accountInfoDO.setBalance(
                accountInfoDO.getBalance().subtract(reqDto.getAmt())
        );
        DoWrapUtil.update(accountInfoDO, false);
        accountInfoDao.save(accountInfoDO);
        //创建账户交易明细
        AccountTranDetailDO detailDO = new AccountTranDetailDO();
        detailDO.setAccountNo(accountInfoDO.getBizCode());
        detailDO.setAmt(reqDto.getAmt().abs());
        detailDO.setFlag(DebitCreditEnum.DECREASE.getCode());
        DoWrapUtil.insert(detailDO, false, false);
        accountTranDetailDao.save(detailDO);
        log.info("更新账户余额end...");
    }
}
